@@ -304,6 +304,7 @@ def consumer_info_api(request): |
||
| 304 | 304 |
coupon_image=coupon.coupon_image, |
| 305 | 305 |
active_at=tc.utc_datetime(), |
| 306 | 306 |
expire_at=coupon.final_expire_at, |
| 307 |
+ is_coupon_admin_writeoff=coupon.is_coupon_admin_writeoff, |
|
| 307 | 308 |
coupon_valid_period=coupon.coupon_valid_period, |
| 308 | 309 |
coupon_limit_model_ids=coupon.coupon_limit_model_ids, |
| 309 | 310 |
coupon_from='PROMOTION', |
@@ -230,6 +230,8 @@ urlpatterns += [ |
||
| 230 | 230 |
url(r'^clerk/integral/list$', sale_views.clerk_integral_list_api, name='clerk_integral_list_api'), # 店员销售积分列表 |
| 231 | 231 |
url(r'^clerk/model/list$', sale_views.clerk_model_list_api, name='clerk_model_list_api'), |
| 232 | 232 |
url(r'^clerk/checkout/serialNo$', sale_views.clerk_checkout_serialNo_api, name='clerk_checkout_serialNo_api'), # 校验序列号 |
| 233 |
+ url(r'^clerk/query/coupon$', sale_views.clerk_query_coupon, name='clerk_query_coupon'), |
|
| 234 |
+ url(r'^clerk/writeoff/coupon$', sale_views.clerk_writeoff_coupon, name='clerk_writeoff_coupon'), |
|
| 233 | 235 |
] |
| 234 | 236 |
|
| 235 | 237 |
urlpatterns += [ |
@@ -61,6 +61,7 @@ class Command(CompatibilityBaseCommand): |
||
| 61 | 61 |
expire_at=tc.utc_datetime(days=365), |
| 62 | 62 |
coupon_valid_period=coupon.coupon_valid_period, |
| 63 | 63 |
coupon_limit_model_ids=coupon.coupon_limit_model_ids, |
| 64 |
+ is_coupon_admin_writeoff=coupon.is_coupon_admin_writeoff, |
|
| 64 | 65 |
) |
| 65 | 66 |
|
| 66 | 67 |
else: |
@@ -0,0 +1,45 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+# Generated by Django 1.11.26 on 2020-04-13 07:43 |
|
| 3 |
+from __future__ import unicode_literals |
|
| 4 |
+ |
|
| 5 |
+from django.db import migrations, models |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+class Migration(migrations.Migration): |
|
| 9 |
+ |
|
| 10 |
+ dependencies = [ |
|
| 11 |
+ ('coupon', '0011_auto_20200411_2316'),
|
|
| 12 |
+ ] |
|
| 13 |
+ |
|
| 14 |
+ operations = [ |
|
| 15 |
+ migrations.AddField( |
|
| 16 |
+ model_name='couponinfo', |
|
| 17 |
+ name='is_coupon_admin_writeoff', |
|
| 18 |
+ field=models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u662f\u7ba1\u7406\u5458\u6838\u9500', verbose_name='is_coupon_admin_writeoff'), |
|
| 19 |
+ ), |
|
| 20 |
+ migrations.AddField( |
|
| 21 |
+ model_name='usercouponinfo', |
|
| 22 |
+ name='clerk_id', |
|
| 23 |
+ field=models.CharField(blank=True, db_index=True, help_text='\u9500\u552e\u5458\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='admin_id'), |
|
| 24 |
+ ), |
|
| 25 |
+ migrations.AddField( |
|
| 26 |
+ model_name='usercouponinfo', |
|
| 27 |
+ name='clerk_name', |
|
| 28 |
+ field=models.CharField(blank=True, db_index=True, help_text='\u9500\u552e\u5458\u540d\u79f0', max_length=32, null=True, verbose_name='clerk_name'), |
|
| 29 |
+ ), |
|
| 30 |
+ migrations.AddField( |
|
| 31 |
+ model_name='usercouponinfo', |
|
| 32 |
+ name='distributor_id', |
|
| 33 |
+ field=models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u552f\u4e00\u6807\u8bc6', max_length=32, null=True, verbose_name='distributor_id'), |
|
| 34 |
+ ), |
|
| 35 |
+ migrations.AddField( |
|
| 36 |
+ model_name='usercouponinfo', |
|
| 37 |
+ name='distributor_name', |
|
| 38 |
+ field=models.CharField(blank=True, db_index=True, help_text='\u7ecf\u9500\u5546\u540d\u79f0', max_length=32, null=True, verbose_name='distributor_name'), |
|
| 39 |
+ ), |
|
| 40 |
+ migrations.AddField( |
|
| 41 |
+ model_name='usercouponinfo', |
|
| 42 |
+ name='is_coupon_admin_writeoff', |
|
| 43 |
+ field=models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u662f\u7ba1\u7406\u5458\u6838\u9500', verbose_name='is_coupon_admin_writeoff'), |
|
| 44 |
+ ), |
|
| 45 |
+ ] |
@@ -33,6 +33,7 @@ class CouponInfo(BaseModelMixin): |
||
| 33 | 33 |
coupon_valid_period = models.IntegerField(_(u'coupon_valid_period'), default=0, help_text=_(u'维修券有效时间(单位:天)')) |
| 34 | 34 |
coupon_expire_at = models.DateTimeField(_(u'coupon_expire_at'), blank=True, null=True, help_text=_(u'维修券过期时间')) |
| 35 | 35 |
|
| 36 |
+ is_coupon_admin_writeoff = models.BooleanField(_(u'is_coupon_admin_writeoff'), default=True, help_text=_(u'是否是管理员核销'), db_index=True) |
|
| 36 | 37 |
coupon_limit_model_ids = JSONField(_(u'coupon_limit_model_ids'), blank=True, null=True, help_text=u'券限制使用 model_ids') |
| 37 | 38 |
|
| 38 | 39 |
class Meta: |
@@ -80,6 +81,12 @@ class UserCouponInfo(BaseModelMixin): |
||
| 80 | 81 |
has_used = models.BooleanField(_(u'has_used'), default=False, help_text=u'是否已核销', db_index=True) |
| 81 | 82 |
admin_id = models.CharField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'核销员唯一标识', db_index=True) |
| 82 | 83 |
used_at = models.DateTimeField(_(u'used_at'), blank=True, null=True, help_text=u'维修券核销时间') |
| 84 |
+ is_coupon_admin_writeoff = models.BooleanField(_(u'is_coupon_admin_writeoff'), default=True, help_text=_(u'是否是管理员核销'), db_index=True) |
|
| 85 |
+ |
|
| 86 |
+ clerk_id = models.CharField(_(u'admin_id'), max_length=32, blank=True, null=True, help_text=u'销售员唯一标识', db_index=True) |
|
| 87 |
+ clerk_name = models.CharField(_(u'clerk_name'), max_length=32, blank=True, null=True, help_text=u'销售员名称', db_index=True) |
|
| 88 |
+ distributor_id = models.CharField(_(u'distributor_id'), max_length=32, blank=True, null=True, help_text=u'经销商唯一标识', db_index=True) |
|
| 89 |
+ distributor_name = models.CharField(_(u'distributor_name'), max_length=32, blank=True, null=True, help_text=u'经销商名称', db_index=True) |
|
| 83 | 90 |
|
| 84 | 91 |
coupon_from = models.CharField(_(u'coupon_from'), default='MEMBER_BENEFITS', max_length=32, blank=True, null=True, help_text=u'劵来源', db_index=True) |
| 85 | 92 |
activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True) |
@@ -12,11 +12,12 @@ from TimeConvert import TimeConvert as tc |
||
| 12 | 12 |
from account.models import UserInfo |
| 13 | 13 |
from integral.models import SaleclerkIntegralIncomeExpensesInfo, SaleclerkSubmitLogInfo |
| 14 | 14 |
from logs.models import MchInfoEncryptLogInfo |
| 15 |
+from coupon.models import UserCouponInfo |
|
| 15 | 16 |
from mch.models import BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo, ModelInfo, SaleclerkInfo |
| 16 | 17 |
from statistic.models import (DistributorSaleStatisticInfo, ModelSaleStatisticInfo, ProvinceSaleStatisticInfo, |
| 17 | 18 |
SaleclerkSaleStatisticInfo, SaleStatisticInfo) |
| 18 | 19 |
from utils.error.errno_utils import (ProductBrandStatusCode, ProductDistributorStatusCode, ProductMachineStatusCode, |
| 19 |
- ProductModelStatusCode, SaleclerkStatusCode) |
|
| 20 |
+ ProductModelStatusCode, SaleclerkStatusCode, CouponStatusCode) |
|
| 20 | 21 |
import os,sys,string |
| 21 | 22 |
|
| 22 | 23 |
|
@@ -420,6 +421,94 @@ def clerk_model_list_api(request): |
||
| 420 | 421 |
|
| 421 | 422 |
|
| 422 | 423 |
@logit |
| 424 |
+def clerk_query_coupon(request): |
|
| 425 |
+ brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK)
|
|
| 426 |
+ user_id = request.POST.get('user_id', '')
|
|
| 427 |
+ user_coupon_id = request.POST.get('user_coupon_id', '')
|
|
| 428 |
+ |
|
| 429 |
+ try: |
|
| 430 |
+ user = UserInfo.objects.get(user_id=user_id, status=True) |
|
| 431 |
+ except UserInfo.DoesNotExist: |
|
| 432 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
| 433 |
+ |
|
| 434 |
+ try: |
|
| 435 |
+ brand = BrandInfo.objects.get(pk=brandID) |
|
| 436 |
+ except BrandInfo.DoesNotExist: |
|
| 437 |
+ brand = None |
|
| 438 |
+ except ValueError: |
|
| 439 |
+ brand = None |
|
| 440 |
+ |
|
| 441 |
+ if not brand: |
|
| 442 |
+ try: |
|
| 443 |
+ brand = BrandInfo.objects.get(brand_id=brandID) |
|
| 444 |
+ except BrandInfo.DoesNotExist: |
|
| 445 |
+ return response(ProductBrandStatusCode.BRAND_NOT_FOUND) |
|
| 446 |
+ |
|
| 447 |
+ try: |
|
| 448 |
+ clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, unionid=user.unionid, status=True) |
|
| 449 |
+ except SaleclerkInfo.DoesNotExist: |
|
| 450 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
| 451 |
+ |
|
| 452 |
+ try: |
|
| 453 |
+ user_coupon = UserCouponInfo.objects.get(user_coupon_id=user_coupon_id) |
|
| 454 |
+ except UserCouponInfo.DoesNotExist: |
|
| 455 |
+ return response(CouponStatusCode.COUPON_NOT_FOUND) |
|
| 456 |
+ |
|
| 457 |
+ return response(200, data={
|
|
| 458 |
+ 'user_coupon': user_coupon.data |
|
| 459 |
+ }) |
|
| 460 |
+ |
|
| 461 |
+@logit |
|
| 462 |
+def clerk_writeoff_coupon(request): |
|
| 463 |
+ brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK)
|
|
| 464 |
+ user_id = request.POST.get('user_id', '')
|
|
| 465 |
+ user_coupon_id = request.POST.get('user_coupon_id', '')
|
|
| 466 |
+ |
|
| 467 |
+ try: |
|
| 468 |
+ user = UserInfo.objects.get(user_id=user_id, status=True) |
|
| 469 |
+ except UserInfo.DoesNotExist: |
|
| 470 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
| 471 |
+ |
|
| 472 |
+ try: |
|
| 473 |
+ brand = BrandInfo.objects.get(pk=brandID) |
|
| 474 |
+ except BrandInfo.DoesNotExist: |
|
| 475 |
+ brand = None |
|
| 476 |
+ except ValueError: |
|
| 477 |
+ brand = None |
|
| 478 |
+ |
|
| 479 |
+ if not brand: |
|
| 480 |
+ try: |
|
| 481 |
+ brand = BrandInfo.objects.get(brand_id=brandID) |
|
| 482 |
+ except BrandInfo.DoesNotExist: |
|
| 483 |
+ return response(ProductBrandStatusCode.BRAND_NOT_FOUND) |
|
| 484 |
+ |
|
| 485 |
+ try: |
|
| 486 |
+ clerk = SaleclerkInfo.objects.get(brand_id=brand.brand_id, unionid=user.unionid, status=True) |
|
| 487 |
+ except SaleclerkInfo.DoesNotExist: |
|
| 488 |
+ return response(SaleclerkStatusCode.CLERK_NOT_FOUND) |
|
| 489 |
+ |
|
| 490 |
+ try: |
|
| 491 |
+ user_coupon = UserCouponInfo.objects.get(user_coupon_id=user_coupon_id) |
|
| 492 |
+ if user_coupon.has_used: |
|
| 493 |
+ return response(CouponStatusCode.COUPON_HAS_USED) |
|
| 494 |
+ elif user_coupon.is_coupon_admin_writeoff: |
|
| 495 |
+ return response(CouponStatusCode.COUPON_PERMISSION_DENIED) |
|
| 496 |
+ elif not user_coupon.has_expired: |
|
| 497 |
+ user_coupon.clerk_id = clerk.clerk_id |
|
| 498 |
+ user_coupon.clerk_name = clerk.clerk_name |
|
| 499 |
+ user_coupon.distributor_id = clerk.distributor_id |
|
| 500 |
+ user_coupon.distributor_name = clerk.distributor_name |
|
| 501 |
+ user_coupon.has_used = True |
|
| 502 |
+ user_coupon.used_at = tc.utc_datetime() |
|
| 503 |
+ user_coupon.save() |
|
| 504 |
+ else: |
|
| 505 |
+ return response(CouponStatusCode.COUPON_EXPIRED) |
|
| 506 |
+ except UserCouponInfo.DoesNotExist: |
|
| 507 |
+ return response(CouponStatusCode.COUPON_NOT_FOUND) |
|
| 508 |
+ |
|
| 509 |
+ return response(200, 'Write Off Coupon Success', u'劵核销成功') |
|
| 510 |
+ |
|
| 511 |
+@logit |
|
| 423 | 512 |
def clerk_checkout_serialNo_api(request): |
| 424 | 513 |
brandID = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_PK)
|
| 425 | 514 |
user_id = request.POST.get('user_id', '')
|
@@ -255,3 +255,10 @@ class TokenStatusCode(BaseStatusCode): |
||
| 255 | 255 |
class PermissionStatusCode(BaseStatusCode): |
| 256 | 256 |
""" 4099xx 权限相关错误码 """ |
| 257 | 257 |
PERMISSION_DENIED = StatusCodeField(409900, 'Permission Denied', description=u'权限不足') |
| 258 |
+ |
|
| 259 |
+class CouponStatusCode(BaseStatusCode): |
|
| 260 |
+ """ 4050xx 优惠劵相关错误码 """ |
|
| 261 |
+ COUPON_NOT_FOUND = StatusCodeField(405001, 'Coupon Not Found', description=u'劵不存在') |
|
| 262 |
+ COUPON_EXPIRED = StatusCodeField(405002, 'Coupon Expired', description=u'劵已过期') |
|
| 263 |
+ COUPON_PERMISSION_DENIED = StatusCodeField(405003, 'Permission Denied', description=u'核销劵权限不足') |
|
| 264 |
+ COUPON_HAS_USED = StatusCodeField(405004, 'Coupon Has Used', description=u'劵已核销') |